/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "底层绘图框架.h"

#include "intern/绘图框架.h"

#include "intern/Vulkan/buffer/Vk缓存.h"
#include "intern/Vulkan/buffer/Vk图像.h"
#include "intern/Vulkan/Vulkan框架.h"
#include "intern/Vulkan/线管/着色器.h"
#include "intern/Vulkan/线管/线管.h"
#include "intern/Vulkan/光追后端.h"



#include "intern/DirectX/DirectX框架.h"
#include <set>

#include "纹理/纹理.h"



#define FENCE_TIMEOUT 100000000





static E_绘图API	g_apiName = E_绘图API::E_DirectX12;
static S_绘图框架*	g_绘图框架 = 0;


static std::set<S_逻辑设备*>	g_物理设备;


S_绘图框架 * f_创建绘图框架(E_绘图API apiName) {
	g_apiName = apiName;

	g_绘图框架 = new S_VK框架();

	return g_绘图框架;
}



void* f_draw_创建绘图设备(S_设备环境& dev) {
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)malloc(sizeof(S_VK渲染环境));
	(*绘图设备配置) = {};

	S_物理设备属性* prop = (S_物理设备属性*)dev.m_物理设备.物理设备属性;
	dev.m_绘图环境 = (S_渲染环境*)绘图设备配置;
	
	绘图设备配置->m_设备 = (VkDevice)(dev.m_逻辑设备.设备);
	绘图设备配置->m_物理设备 = (VkPhysicalDevice)(dev.m_物理设备.设备);
	绘图设备配置->交换链列队家族Offset = dev.m_逻辑设备.队列族索引;
	绘图设备配置->绘图列队家族Offset = dev.m_逻辑设备.队列族索引;
	
	
	绘图设备配置->m_当前帧ID = 0;
	绘图设备配置->m_列队ID = 0;
	
	绘图设备配置->m_图形列队 = (VkQueue*)calloc(10, sizeof(VkQueue));
	for (uint8 i = 0; i < 10; ++i) {
		vkGetDeviceQueue(绘图设备配置->m_设备, 绘图设备配置->绘图列队家族Offset, i, &(绘图设备配置->m_图形列队[i]));
	}
	
	
	f_vk创建命令缓存池(绘图设备配置);
	绘图设备配置->m_命令缓存 = f_vk创建命令缓存(绘图设备配置, 1);
	f_vk创建同步围栏(绘图设备配置);
	
	return 绘图设备配置;
}

void f_draw_销毁绘图设备(void* 绘图设备) {
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)绘图设备;

	f_vk销毁命令缓存(绘图设备配置, 绘图设备配置->m_命令缓存);

	free(绘图设备配置);
}






E_绘图API f_get后端框架名称() {
	return g_apiName;
}

void * f_get设备() {
	return g_绘图框架->f_get设备();
}

void * f_get命令列表() {
	return g_绘图框架->f_get命令列表();
}

void * f_get环境() {
	return g_绘图框架->f_get环境();
}


S_着色* f_create着色(S_设备环境& ctx, S_着色器创建配置 ini, S_结构对象** 布局, uint32 布局数量) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), ini.m_Paths.size(), "shader_n1");
	for (uint32 i = 0; i < ini.m_Paths.size(); ++i) {
		shader->f_从文件载入着色器(ini.m_Paths[i], i);
	}
	shader->f_init着色参数布局(ini, 布局, 布局数量);
	return shader;
}

S_着色* f_create着色(S_设备环境& ctx, S_着色器管线创建参数 ini) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), ini.m_Paths.size(), "shader_n1");
	for (uint32 i = 0; i < ini.m_Paths.size(); ++i) {
		shader->f_从文件载入着色器(ini.m_Paths[i], i);
	}
	shader->f_构建管线布局(ini.m_参数布局, ini.m_常量偏移和字节数);
	return shader;
}

S_管线* f_create线管(S_设备环境& ctx, S_着色& shader, const S_线管创建参数& 线管参数, std::string name) {
	S_Vk线管* pipeline = new S_Vk线管(ctx, name);
	pipeline->f_创建线管(线管参数, shader, 线管参数.m_槽);
	return pipeline;
}




S_着色* f_df_创建渲染着色器(S_设备环境& ctx, S_着色器管线创建参数 ini) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), ini.m_Paths.size(), "shader_n1");
	for (uint32 i = 0; i < ini.m_Paths.size(); ++i) {
		shader->f_从文件载入着色器(ini.m_Paths[i], i);
	}
	shader->f_构建顶点布局(ini.m_顶点配置);
	shader->f_构建管线布局(ini.m_参数布局, ini.m_常量偏移和字节数);
	return shader;
}



S_管线* f_df_创建计算线管(S_设备环境& ctx, S_着色& shader, std::string name) {
	S_Vk计算线管* pipeline = new S_Vk计算线管(ctx, name);
	pipeline->f_创建线管(shader);
	return pipeline;
}

S_着色* f_df_创建计算着色管线(S_设备环境& ctx, S_着色器管线创建参数 ini) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), ini.m_Paths.size(), "shader_n1");
	for (uint32 i = 0; i < ini.m_Paths.size(); ++i) {
		shader->f_从文件载入着色器(ini.m_Paths[i], i);
	}
	shader->f_构建管线布局(ini.m_参数布局, ini.m_常量偏移和字节数);
	return shader;
}

S_着色线管* f_df_创建材质着色器(S_设备环境& ctx,
							S_材质管线* material, 
							const S_着色器创建配置& 图元配置, 
							S_线管创建参数& 线管参数, 
							S_结构对象** 布局,
							uint32 布局数量,
							E_管线槽 管线槽) {
	线管参数.m_槽 = 管线槽;
	switch (管线槽) {
		
		case E_管线槽::e_颜色渲染: {
			if (!material->m_着色线管) {
				material->m_着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_着色线管->m_Shader = f_create着色(ctx, 图元配置, 布局, 布局数量);
			material->m_着色线管->m_Pipeline = f_create线管(ctx, *material->m_着色线管->m_Shader, 线管参数);
			if (!布局数量) material->m_着色线管->m_Shader->f_alloc参数设置(&(material->m_着色线管->m_GPU参数set));

			material->m_着色线管->m_参数布局 = nullptr;
			return material->m_着色线管;
		}
		case E_管线槽::e_阴影渲染: {
			if (!material->m_阴影着色线管) {
				material->m_阴影着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_阴影着色线管->m_Shader = f_create着色(ctx, 图元配置, 布局, 布局数量);
			material->m_阴影着色线管->m_Pipeline = f_create线管(ctx, *material->m_阴影着色线管->m_Shader, 线管参数);
			if (!布局数量) material->m_阴影着色线管->m_Shader->f_alloc参数设置(&(material->m_阴影着色线管->m_GPU参数set));

			material->m_阴影着色线管->m_参数布局 = nullptr;
			return material->m_阴影着色线管;
		}
		case E_管线槽::e_环境渲染: {
			if (!material->m_环境着色线管) {
				material->m_环境着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_环境着色线管->m_Shader = f_create着色(ctx, 图元配置, 布局, 布局数量);
			material->m_环境着色线管->m_Pipeline = f_create线管(ctx, *material->m_环境着色线管->m_Shader, 线管参数);
			if (!布局数量) material->m_环境着色线管->m_Shader->f_alloc参数设置(&(material->m_环境着色线管->m_GPU参数set));

			material->m_环境着色线管->m_参数布局 = nullptr;
			return material->m_环境着色线管;
		}
		case E_管线槽::e_几何渲染: {
			if (!material->m_几何着色线管) {
				material->m_几何着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_几何着色线管->m_Shader = f_create着色(ctx, 图元配置, 布局, 布局数量);
			material->m_几何着色线管->m_Pipeline = f_create线管(ctx, *material->m_几何着色线管->m_Shader, 线管参数);
			if (!布局数量) material->m_几何着色线管->m_Shader->f_alloc参数设置(&(material->m_几何着色线管->m_GPU参数set));

			material->m_几何着色线管->m_参数布局 = nullptr;
			return material->m_几何着色线管;
		}
		case E_管线槽::e_UI渲染: {
			if (!material->m_UI渲染线管) {
				material->m_UI渲染线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_UI渲染线管->m_Shader = f_create着色(ctx, 图元配置, 布局, 布局数量);
			material->m_UI渲染线管->m_Pipeline = f_create线管(ctx, *material->m_UI渲染线管->m_Shader, 线管参数);
			if (!布局数量) material->m_UI渲染线管->m_Shader->f_alloc参数设置(&(material->m_UI渲染线管->m_GPU参数set));

			material->m_UI渲染线管->m_参数布局 = nullptr;
			return material->m_UI渲染线管;
		}
		case E_管线槽::e_UI合成: {
			if (!material->m_UI合成线管) {
				material->m_UI合成线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			
			material->m_UI合成线管->m_Shader = f_create着色(ctx, 图元配置, 布局, 布局数量);
			material->m_UI合成线管->m_Pipeline = f_create线管(ctx, *material->m_UI合成线管->m_Shader, 线管参数);
			if (!布局数量) material->m_UI合成线管->m_Shader->f_alloc参数设置(&(material->m_UI合成线管->m_GPU参数set));

			material->m_UI合成线管->m_参数布局 = nullptr;
			return material->m_UI合成线管;
		}
		default:
			break;
	}
	assert(0);
	return nullptr;
}

S_着色线管* f_df_创建材质着色器(S_设备环境& ctx, S_材质管线* material, const S_着色器创建配置& 图元配置, S_线管创建参数& 线管参数, E_管线槽 管线槽) {
	线管参数.m_槽 = 管线槽;
	switch (管线槽) {

		case E_管线槽::e_颜色渲染: {
			if (!material->m_着色线管) {
				material->m_着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_着色线管->m_Shader = f_create着色(ctx, 图元配置);
			material->m_着色线管->m_Pipeline = f_create线管(ctx, *material->m_着色线管->m_Shader, 线管参数);

			material->m_着色线管->m_参数布局 = nullptr;
			return material->m_着色线管;
		}
		case E_管线槽::e_阴影渲染: {
			if (!material->m_阴影着色线管) {
				material->m_阴影着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_阴影着色线管->m_Shader = f_create着色(ctx, 图元配置);
			material->m_阴影着色线管->m_Pipeline = f_create线管(ctx, *material->m_阴影着色线管->m_Shader, 线管参数);

			material->m_阴影着色线管->m_参数布局 = nullptr;
			return material->m_阴影着色线管;
		}
		case E_管线槽::e_环境渲染: {
			if (!material->m_环境着色线管) {
				material->m_环境着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_环境着色线管->m_Shader = f_create着色(ctx, 图元配置);
			material->m_环境着色线管->m_Pipeline = f_create线管(ctx, *material->m_环境着色线管->m_Shader, 线管参数);

			material->m_环境着色线管->m_参数布局 = nullptr;
			return material->m_环境着色线管;
		}
		case E_管线槽::e_几何渲染: {
			if (!material->m_几何着色线管) {
				material->m_几何着色线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_几何着色线管->m_Shader = f_create着色(ctx, 图元配置);
			material->m_几何着色线管->m_Pipeline = f_create线管(ctx, *material->m_几何着色线管->m_Shader, 线管参数);

			material->m_几何着色线管->m_参数布局 = nullptr;
			return material->m_几何着色线管;
		}
		case E_管线槽::e_UI渲染: {
			if (!material->m_UI渲染线管) {
				material->m_UI渲染线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}
			material->m_UI渲染线管->m_Shader = f_create着色(ctx, 图元配置);
			material->m_UI渲染线管->m_Pipeline = f_create线管(ctx, *material->m_UI渲染线管->m_Shader, 线管参数);

			material->m_UI渲染线管->m_参数布局 = nullptr;
			return material->m_UI渲染线管;
		}
		case E_管线槽::e_UI合成: {
			if (!material->m_UI合成线管) {
				material->m_UI合成线管 = (S_着色线管*)malloc(sizeof(S_着色线管));
			}

			material->m_UI合成线管->m_Shader = f_create着色(ctx, 图元配置);
			material->m_UI合成线管->m_Pipeline = f_create线管(ctx, *material->m_UI合成线管->m_Shader, 线管参数);

			material->m_UI合成线管->m_参数布局 = nullptr;
			return material->m_UI合成线管;
		}
		default:
			break;
	}
	assert(0);
	return nullptr;
}

void f_df_创建材质管线(S_设备环境& ctx,
					 S_材质管线* material, 
					 const S_着色器创建配置& 图元配置, 
					 S_线管创建参数& 线管参数, 
					 S_结构对象** 布局,
					 uint32 布局数量,
					 uint32 管线槽) {

	
	if (管线槽 & E_管线槽::e_颜色渲染) {
		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, 布局, 布局数量, E_管线槽::e_颜色渲染);
	}
	if (管线槽 & E_管线槽::e_阴影渲染) {
		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, 布局, 布局数量, E_管线槽::e_阴影渲染);
	}
	if (管线槽 & E_管线槽::e_环境渲染) {
		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, 布局, 布局数量, E_管线槽::e_环境渲染);
	}
	if (管线槽 & E_管线槽::e_几何渲染) {
		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, 布局, 布局数量, E_管线槽::e_几何渲染);
	}
	if (管线槽 & E_管线槽::e_UI渲染) {
		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, 布局, 布局数量, E_管线槽::e_UI渲染);
	}
	if (管线槽 & E_管线槽::e_UI合成) {
		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, 布局, 布局数量, E_管线槽::e_UI合成);
	}
}

//void f_df_创建材质管线(S_设备环境& ctx,
//				 S_材质管线* material, 
//				 const S_着色器创建配置& 图元配置, 
//				 S_线管创建参数& 线管参数, 
//				 uint32 管线槽) {
//
//
//	if (管线槽 & E_管线槽::e_颜色渲染) {
//		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, E_管线槽::e_颜色渲染);
//	}
//	if (管线槽 & E_管线槽::e_阴影渲染) {
//		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, E_管线槽::e_阴影渲染);
//	}
//	if (管线槽 & E_管线槽::e_环境渲染) {
//		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, E_管线槽::e_环境渲染);
//	}
//	if (管线槽 & E_管线槽::e_几何渲染) {
//		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, E_管线槽::e_几何渲染);
//	}
//	if (管线槽 & E_管线槽::e_UI渲染) {
//		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, E_管线槽::e_UI渲染);
//	}
//	if (管线槽 & E_管线槽::e_UI合成) {
//		f_df_创建材质着色器(ctx, material, 图元配置, 线管参数, E_管线槽::e_UI合成);
//	}
//}

void f_df_创建渲染着色管线(S_设备环境& ctx, S_材质管线* material, const S_着色器管线创建参数& 图元配置, const S_线管创建参数& 线管参数, uint32 管线槽) {
	auto shader = f_df_创建渲染着色器(ctx, 图元配置);
	
	
	auto 管线包 = [&](E_管线槽 槽) -> S_着色线管* {
		S_着色线管* 管线组 = (S_着色线管*)malloc(sizeof(S_着色线管));

		管线组->m_Shader = shader;
		管线组->m_Pipeline = new S_Vk线管(ctx, "");
		管线组->m_Pipeline->f_创建线管(线管参数, *shader, 槽);

		//for (auto& e : 图元配置.m_参数布局) {
		// 
		//}
		管线组->m_Pipeline->m_线管布局 = (S_结构指针)(((S_Vk着色*)shader)->m_线管布局);

		return 管线组;
	};

	
	if (管线槽 & E_管线槽::e_颜色渲染) {
		assert(!material->m_着色线管);
		if (!material->m_着色线管) material->m_着色线管 = 管线包(E_管线槽::e_颜色渲染);
	}
	if (管线槽 & E_管线槽::e_阴影渲染) {
		assert(!material->m_阴影着色线管);
		if (!material->m_阴影着色线管) material->m_阴影着色线管 = 管线包(E_管线槽::e_阴影渲染);
	}
	if (管线槽 & E_管线槽::e_环境渲染) {
		assert(!material->m_环境着色线管);
		if (!material->m_环境着色线管) material->m_环境着色线管 = 管线包(E_管线槽::e_环境渲染);
	}
	if (管线槽 & E_管线槽::e_几何渲染) {
		assert(!material->m_几何着色线管);
		if (!material->m_几何着色线管) material->m_几何着色线管 = 管线包(E_管线槽::e_几何渲染);
	}
	if (管线槽 & E_管线槽::e_UI渲染) {
		assert(!material->m_UI渲染线管);
		if (!material->m_UI渲染线管) material->m_UI渲染线管 = 管线包(E_管线槽::e_UI渲染);
	}
	if (管线槽 & E_管线槽::e_UI合成) {
		assert(!material->m_UI合成线管);
		if (!material->m_UI合成线管) material->m_UI合成线管 = 管线包(E_管线槽::e_UI合成);
	}
}

void f_df_销毁材质着色器(S_材质管线* material) {
	if (material->m_着色线管) {
		if (material->m_着色线管->m_GPU参数set) material->m_着色线管->m_Shader->f_free参数设置(&(material->m_着色线管->m_GPU参数set));
		if (material->m_着色线管->m_Shader) delete material->m_着色线管->m_Shader;
		if (material->m_着色线管->m_Pipeline) delete material->m_着色线管->m_Pipeline;

		material->m_着色线管->m_GPU参数set = nullptr;
		material->m_着色线管->m_Shader = nullptr;
		material->m_着色线管->m_Pipeline = nullptr;
	}

	if (material->m_阴影着色线管) {
		if (material->m_阴影着色线管->m_GPU参数set) material->m_阴影着色线管->m_Shader->f_free参数设置(&(material->m_阴影着色线管->m_GPU参数set));
		if (material->m_阴影着色线管->m_Shader) delete material->m_阴影着色线管->m_Shader;
		if (material->m_阴影着色线管->m_Pipeline) delete material->m_阴影着色线管->m_Pipeline;

		material->m_阴影着色线管->m_GPU参数set = nullptr;
		material->m_阴影着色线管->m_Shader = nullptr;
		material->m_阴影着色线管->m_Pipeline = nullptr;
	}

	if (material->m_环境着色线管) {
		if (material->m_环境着色线管->m_GPU参数set) material->m_环境着色线管->m_Shader->f_free参数设置(&(material->m_环境着色线管->m_GPU参数set));
		if (material->m_环境着色线管->m_Shader) delete material->m_环境着色线管->m_Shader;
		if (material->m_环境着色线管->m_Pipeline) delete material->m_环境着色线管->m_Pipeline;

		material->m_环境着色线管->m_GPU参数set = nullptr;
		material->m_环境着色线管->m_Shader = nullptr;
		material->m_环境着色线管->m_Pipeline = nullptr;
	}

	if (material->m_几何着色线管) {
		if (material->m_几何着色线管->m_GPU参数set) material->m_几何着色线管->m_Shader->f_free参数设置(&(material->m_几何着色线管->m_GPU参数set));
		if (material->m_几何着色线管->m_Shader) delete material->m_几何着色线管->m_Shader;
		if (material->m_几何着色线管->m_Pipeline) delete material->m_几何着色线管->m_Pipeline;

		material->m_几何着色线管->m_GPU参数set = nullptr;
		material->m_几何着色线管->m_Shader = nullptr;
		material->m_几何着色线管->m_Pipeline = nullptr;
	}
}

void f_df_构建着色器描述符集(S_着色线管* 材质管线, std::vector<C_DescriptorSet*>& ds) {
	auto& vkDs = static_cast<S_Vk线管*>(材质管线->m_Pipeline)->m_DS;

	for (auto& e : ds) {
		auto& dc = static_cast<C_VkDescriptorSet*>(e)->m_DS;
		vkDs.insert(vkDs.end(), dc.begin(), dc.end());
	}
}




t_着色参数设置 f_df_创建着色器参数布局(void* device, const std::vector<S_着色器创建参数>& 参数布局, S_GPU参数槽* 分配槽) {
	S_GPU参数设置描述* 布局 = f_vkShader_创建参数布局((VkDevice)device, 参数布局);
	if(分配槽) {
		f_df_allocGPU参数缓存槽(分配槽, 参数布局.size());
		分配槽->m_GPU布局描述 = (S_结构对象*)布局;
	}
	return (S_结构对象*)布局;
}

C_DescriptorSetLayout* f_df_创建着色器参数布局(S_设备环境& ctx, const std::vector<S_着色器创建参数>& 参数布局) {
	return new C_VkDescriptorSetLayout(ctx, 参数布局);
}

void f_df_绑定参数布局(S_设备环境& ctx, S_结构对象* 参数布局) {
	f_vkShader_销毁参数布局((VkDevice)ctx.m_逻辑设备.设备, (S_GPU参数设置描述*)参数布局);
}

void f_df_销毁绑定参数布局(S_设备环境& ctx, S_结构对象* 参数布局) {
	f_vkShader_销毁参数布局((VkDevice)ctx.m_逻辑设备.设备, (S_GPU参数设置描述*)参数布局);
}

S_管线* f_df_create光追管线(S_设备环境& ctx, S_光追后端* 光追后端, const S_着色器创建配置& 线管参数) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), 线管参数.m_Paths.size(), "光追着色");
	uint32 num = 线管参数.m_Paths.size();

	for (uint32 i = 0; i < num; ++i) {
		光追后端->m_着色器组ID.insert(std::make_pair(线管参数.m_Paths[i].阶段, i));
	}

	uint32 generalShader = 0;
	for (uint32 i = 0; i < num; ++i) {
		std::cout<<"vkRay shader:"<< 线管参数.m_Paths[i].path << std::endl;
		shader->f_从文件载入着色器(线管参数.m_Paths[i], generalShader, true);
		++generalShader;
	}


	f_vkShader_构建着色器组信息(shader);

	shader->f_initRT着色参数布局(线管参数);

	std::cout << "create Vulkan Ray pipeline" << std::endl;
	S_Vk光追线管* pl = new S_Vk光追线管(ctx, "光追管线");
	pl->f_创建线管(线管参数, *shader);
	pl->m_着色 = shader;
	
	return pl;
}

S_光追后端* f_df_create光追后端(S_设备环境& ctx, const S_着色器创建配置& 线管参数) {
	C_Vk光追后端* b = new C_Vk光追后端(ctx);

	if (ctx.m_支持光追) {
		b->m_线管创建配置信息 = 线管参数;
		b->m_光追管线 = f_df_create光追管线(ctx, b, 线管参数);

		std::cout << "create Vulkan Ray shaderGroupHandle" << std::endl;
		b->f_构建着色绑定列表();

		f_df_allocGPU参数缓存槽(&b->m_参数布局, 11);
	}
	
	return b;
}

void f_df_销毁光追后端(S_光追后端* 光追后端) {
	delete 光追后端;
}

void f_df_光追后端_重构着色器(S_光追后端* rt) {
	//((S_Vk光追线管*)rt->m_后端_光追管线)->m_着色->f_从文件载入着色器(path, E_着色阶段::e_光追回调, i, true);
}






void f_push板载缓存(S_着色* shader, void* data, uint64 bitSize){
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(shader);
	s->m_设备;
}

S_结构指针 f_gpu_创建参数布局(S_板载缓存* 渲染参数, uint32 binding, uint32 阶段分布) {
	VkDevice 设备 = (VkDevice)(渲染参数->m_Ctx.m_逻辑设备.设备);

	vector<VkDescriptorPoolSize>			描述池大小;

	VkDescriptorSetLayoutBinding lb{};
	lb.binding = binding;
	lb.descriptorCount = 1;
	lb.descriptorType = (VkDescriptorType)f_get缓存布局类型(渲染参数->m_Type);
	lb.stageFlags = f_vk_get参数布局着色阶段(阶段分布);

	VkDescriptorPoolSize ps;
	ps.type = lb.descriptorType;
	ps.descriptorCount = 1;
	描述池大小.push_back(ps);


	VkDescriptorSetLayoutCreateInfo 布局创建信息 = {};
	布局创建信息.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
	布局创建信息.pNext = NULL;
	布局创建信息.bindingCount = 1;
	布局创建信息.pBindings = &lb;

	VkDescriptorSetLayout m_参数布局;
	if (vkCreateDescriptorSetLayout(设备, &布局创建信息, nullptr, &m_参数布局) != VK_SUCCESS) {
		throw std::runtime_error("创建 GPU参数资源布局失败");
	}


	VkDescriptorPoolCreateInfo 描述池创建信息 = {};
	描述池创建信息.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
	描述池创建信息.pNext = 0;
	描述池创建信息.maxSets = 32;
	描述池创建信息.poolSizeCount = 描述池大小.size();
	描述池创建信息.pPoolSizes = 描述池大小.data();

	VkDescriptorPool 参数池;
	auto res = vkCreateDescriptorPool(设备, &描述池创建信息, 0, &参数池);
	assert(res == VK_SUCCESS);

	

	VkDescriptorSetAllocateInfo m_描述集列表分配信息 = {};
	m_描述集列表分配信息.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
	m_描述集列表分配信息.pNext = 0;
	m_描述集列表分配信息.descriptorPool = 参数池;
	m_描述集列表分配信息.descriptorSetCount = 1;
	m_描述集列表分配信息.pSetLayouts = &m_参数布局;

	VkDescriptorSet 描述集列表 = nullptr;
	res = vkAllocateDescriptorSets(设备, &m_描述集列表分配信息, &描述集列表);
	assert(res == VK_SUCCESS);

	return (S_结构指针)描述集列表;
}

void f_setGPU参数布局_2D绘制(S_着色* shader, S_2D绘制GPU全局参数& view) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(shader);
	//VkDevice 设备 = s->m_设备;

	S_VkArray缓存* 视图矩阵 = dynamic_cast<S_VkArray缓存*>((S_板载缓存*)(view.m_视图矩阵));
	S_2D笔刷& 笔刷 = *((S_2D笔刷*)(view.m_2D笔刷));


	std::vector<VkWriteDescriptorSet> writes(笔刷.m_参数元素数量 + 笔刷.m_纹理参数数量 + 1);	 //完善一致变量写入描述集实例数组
	//std::vector<VkWriteDescriptorSet> writes(笔刷.m_参数元素数量 + 笔刷.m_纹理参数数量);		 //完善一致变量写入描述集实例数组

	//视图矩阵
	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;							//结构体类型
	writes[0].pNext = NULL;																//自定义数据的指针
	writes[0].descriptorCount = 1;														//描述数量
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;						//描述类型
	writes[0].pBufferInfo = &(视图矩阵->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
	writes[0].dstArrayElement = 0;														//目标数组起始元素
	writes[0].dstBinding = 0;															//目标绑定编号
	writes[0].dstSet = (VkDescriptorSet)(笔刷.g_材质->m_着色线管->m_GPU参数set);



	for (uint32 i = 0; i < 笔刷.m_参数元素数量; ++i) {
		
		uint16 id = i + 1;

		switch (笔刷.m_参数类型[i]) {
			case E_板载缓存类型::e_SAMPLER_Array: {
				writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
				writes[id].pNext = nullptr;
				writes[id].descriptorType = (VkDescriptorType)f_get缓存布局类型(E_板载缓存类型::e_SAMPLER_Array);
				writes[id].dstArrayElement = 0;													
				writes[id].dstBinding = 笔刷.m_绑定位置[i];
				writes[id].dstSet = (VkDescriptorSet)(笔刷.g_材质->m_着色线管->m_GPU参数set);

				S_纹理集* 纹理集 = (S_纹理集*)(笔刷.m_参数槽[i]);
				writes[id].pImageInfo = (VkDescriptorImageInfo*)(纹理集->data->ptr_userData );
				writes[id].descriptorCount = 纹理集->data->count;
				break;
			}

			default: {
				auto buf = (S_VkArray缓存*)(笔刷.m_参数槽[i]);

				writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						//结构体类型
				writes[id].pNext = nullptr;														//自定义数据的指针
				writes[id].descriptorCount = 1;													//描述数量
				writes[id].descriptorType = (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
				writes[id].pBufferInfo = &(buf->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
				writes[id].dstArrayElement = 0;													//目标数组起始元素
				writes[id].dstBinding = 笔刷.m_绑定位置[i];										//目标绑定编号
				writes[id].dstSet = (VkDescriptorSet)(笔刷.g_材质->m_着色线管->m_GPU参数set);
				writes[id].pImageInfo = 0;
				break;
			}
		}
	}

	int32 Binding = DEF_BINDING_WIDGET_Texture;
	for (uint32 i = 0; i < 笔刷.m_纹理参数数量; ++i) {
		uint16 id = 笔刷.m_参数元素数量 + i + 1;
		//uint16 id = 笔刷.m_参数元素数量 + i;

		if ((VkDescriptorSet)view.m_GPU参数 == nullptr) {
			cout << view.m_GPU参数;
		}
		writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;				//结构体类型
		writes[id].pNext = NULL;												//自定义数据的指针
		writes[id].descriptorCount = 1;
		writes[id].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
		writes[id].pBufferInfo = 0;
		writes[id].dstArrayElement = 0;
		writes[id].dstBinding = Binding;												//目标绑定编号
		writes[id].dstSet = (VkDescriptorSet)(笔刷.g_材质->m_着色线管->m_GPU参数set);
		writes[id].pImageInfo = &(((S_VkImage*)笔刷.m_纹理信息[i])->m_纹理信息);

		if (!writes[id].pImageInfo) {
			std::cout << "纹理参数[i]" << std::endl;
		}

		++Binding;
	}

	vkUpdateDescriptorSets(s->m_设备, writes.size(), writes.data(), 0, NULL);
}



void f_setGPU参数布局(S_GPU计算* GPU, const S_GPU参数布局& GPU参数) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(GPU->m_Shader);

	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_绑定数量);						

	for (uint32 i = 0; i < GPU参数.m_绑定数量; ++i) {
		auto buf = dynamic_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);

		writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						//结构体类型
		writes[i].pNext = NULL;															//自定义数据的指针
		writes[i].descriptorCount = 1;													//描述数量
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
		writes[i].pBufferInfo = &(buf->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding = GPU参数.m_绑定位置[i];									//目标绑定编号
		writes[i].dstSet = (VkDescriptorSet)GPU->m_GPU参数set;
		writes[i].pImageInfo = 0;
	}

	vkUpdateDescriptorSets(s->m_设备, writes.size(), writes.data(), 0, NULL);
}

void f_df_upGPU计算参数(S_GPU计算* device, const S_GPU参数槽& GPU参数) {
	f_df_upGPU参数(device->m_Ctx.m_逻辑设备.设备, device->m_GPU参数set, GPU参数);
}

void f_df_setGPU参数布局(S_结构指针 device, const S_GPU参数槽& GPU参数, bool 内存块) {
	VkDevice 设备 = (VkDevice)device;

	uint32 纹理数量 = GPU参数.m_纹理槽 != nullptr ? GPU参数.m_纹理槽->m_槽数量 : 0;
	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量 + 纹理数量);
	
	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		writes[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };

		switch (GPU参数.m_参数类型[i]) {
			case E_板载缓存类型::e_UBO: {
				writes[i].pBufferInfo = &(((S_VkArray缓存*)(GPU参数.m_参数槽[i]))->m_Data.m_Buffer_info);
				break;
			}
			case E_板载缓存类型::e_IMAGE_SAMPLER:
			case E_板载缓存类型::e_SAMPLER:
			case E_板载缓存类型::e_IMAGE: {
				writes[i].pImageInfo = &(((S_VkImage*)(GPU参数.m_参数槽[i]))->m_纹理信息);
				break;
			}
			case E_板载缓存类型::e_SSBO: {
				if (内存块) {
					auto& 块 = *(S_GPU内存块*)(GPU参数.m_参数槽[i]);
					auto& buf = *static_cast<S_VkArray缓存*>(块.m_Buf);
					writes[i].pBufferInfo = &(buf.m_Data.m_Buffer_info);
				}
				else {
					writes[i].pBufferInfo = &( ((S_VkArray缓存*)(GPU参数.m_参数槽[i]))->m_Data.m_Buffer_info );
				}
				
				break;
			}
		}

		writes[i].descriptorCount = GPU参数.m_绑定数量[i];
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(E_板载缓存类型(GPU参数.m_参数类型[i]));
		writes[i].dstArrayElement = 0;
		writes[i].dstBinding = GPU参数.m_绑定位置[i];
		writes[i].dstSet = ((S_GPU参数设置描述*)GPU参数.m_GPU布局描述)->m_DescriptorSet;
	}

	if (纹理数量) {
		for (uint32 i = 0; i < GPU参数.m_纹理槽->m_槽数量; ++i) {
			writes[GPU参数.m_参数数量 + i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };

			writes[GPU参数.m_参数数量 + i].pImageInfo = (VkDescriptorImageInfo*)(GPU参数.m_纹理槽->m_纹理信息[i]);
			writes[GPU参数.m_参数数量 + i].descriptorCount = GPU参数.m_纹理槽->m_绑定数量[i];
			writes[GPU参数.m_参数数量 + i].dstBinding = GPU参数.m_纹理槽->m_绑定位置[i];

			writes[GPU参数.m_参数数量 + i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
			writes[GPU参数.m_参数数量 + i].dstArrayElement = 0;
			writes[GPU参数.m_参数数量 + i].dstSet = ((S_GPU参数设置描述*)GPU参数.m_GPU布局描述)->m_DescriptorSet;
		}
	}


	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, NULL);
}

void f_df_upGPU参数(S_结构指针 device, S_结构指针 GPU参数设置, const S_GPU参数槽& GPU参数, bool 内存块) {
	assert(GPU参数.m_参数数量);
	//if(!GPU参数设置) return;
	VkDevice 设备 = (VkDevice)device;
	VkDescriptorSet DS = (VkDescriptorSet)GPU参数设置;

	uint32 纹理数量 = GPU参数.m_纹理槽 != nullptr ? GPU参数.m_纹理槽->m_槽数量 : 0;
	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量 + 纹理数量);




	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		writes[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
		
		switch (GPU参数.m_参数类型[i]) {
			case E_板载缓存类型::e_光追BVH: {
				if (内存块) {
					auto& 块 = *(S_GPU内存块*)(GPU参数.m_参数槽[i]);
					f_buf_get加速结构(块);
					writes[i].pNext = 块.m_Acc;
				}
				else {
					writes[i].pNext = GPU参数.m_参数槽[i];
				}
				break;
			}

			case E_板载缓存类型::e_纹理储存_Array:
			case E_板载缓存类型::e_IMAGE_Array:
			case E_板载缓存类型::e_SAMPLER_Array: {
				writes[i].pImageInfo = (VkDescriptorImageInfo*)(GPU参数.m_参数槽[i]);
				break;
			}
			case E_板载缓存类型::e_IMAGE_SAMPLER:
			case E_板载缓存类型::e_SAMPLER:
			case E_板载缓存类型::e_IMAGE: {
				writes[i].pImageInfo = &(((S_VkImage*)(GPU参数.m_参数槽[i]))->m_纹理信息);
				break;
			}
			case E_板载缓存类型::e_UBO: {
				writes[i].pBufferInfo = &( ((S_VkArray缓存*)(GPU参数.m_参数槽[i]))->m_Data.m_Buffer_info );
				break;
			}    
			case E_板载缓存类型::e_图像缓存: {
				writes[i].pBufferInfo = &(((S_VkArray缓存*)(GPU参数.m_参数槽[i]))->m_Data.m_Buffer_info);
				//writes[i].pImageInfo = &(((S_VkImage*)(GPU参数.m_参数槽[i]))->m_着色器参数);
				break;
			}
			case E_板载缓存类型::e_光追实例: {
				auto& 块 = *(S_GPU内存块*)(GPU参数.m_参数槽[i]);
				auto& buf = *static_cast<S_VkArray缓存*>(块.m_Buf);
				writes[i].pBufferInfo = &buf.m_Data.m_Buffer_info;
				break;
			}
			default: {
				if (内存块) {
					auto& 块 = *(S_GPU内存块*)(GPU参数.m_参数槽[i]);
					auto& buf = *static_cast<S_VkArray缓存*>(块.m_Buf);
					writes[i].pBufferInfo = &buf.m_Data.m_Buffer_info;
				}
				else {
					auto& buf = *static_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);
					writes[i].pBufferInfo = &buf.m_Data.m_Buffer_info;
				}
				break;
			}
		}

		writes[i].descriptorCount = GPU参数.m_绑定数量[i];						
		writes[i].descriptorType  = (VkDescriptorType)f_get缓存布局类型(E_板载缓存类型(GPU参数.m_参数类型[i]));
		writes[i].dstArrayElement = 0;										
		writes[i].dstBinding      = GPU参数.m_绑定位置[i];			
		writes[i].dstSet          = DS;
	}

	if (纹理数量) {
		for (uint32 i = 0; i < GPU参数.m_纹理槽->m_槽数量; ++i) {
			f_纹理槽_设置GPU参数(*GPU参数.m_纹理槽, writes[GPU参数.m_参数数量 + i], DS, i);
			//writes[GPU参数.m_参数数量 + i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
			//writes[GPU参数.m_参数数量 + i].pImageInfo = (VkDescriptorImageInfo*)(GPU参数.m_纹理槽->m_纹理信息[i]);
			//writes[GPU参数.m_参数数量 + i].descriptorCount = GPU参数.m_纹理槽->m_绑定数量[i];
			//writes[GPU参数.m_参数数量 + i].dstBinding = GPU参数.m_纹理槽->m_绑定位置[i];
			//writes[GPU参数.m_参数数量 + i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
			//writes[GPU参数.m_参数数量 + i].dstArrayElement = 0;
			//writes[GPU参数.m_参数数量 + i].dstSet = DS;
		}
	}
	
	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, VK_NULL_HANDLE);
}

void f_df_upGPU参数(S_结构指针 device, const S_GPU参数槽& GPU参数, bool 内存块) {
	VkDescriptorSet s = ((S_GPU参数设置描述*)GPU参数.m_GPU布局描述)->m_DescriptorSet;
	f_df_upGPU参数(device, (S_结构指针)s, GPU参数, 内存块);
}




Inline void f_绑定Vertex(S_VK渲染环境* info, S_VkArray缓存* buf) {
	//S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;
	VkDeviceSize f[1] = { 0 };
	//顶点数据偏移量数组
	vkCmdBindVertexBuffers(info->m_命令缓存, 0, 1, &(buf->m_Data.m_Buf), f);
}

void f_Ex绑定Index(S_设备环境& ctx, S_板载缓存* buf) {
	S_VkArray缓存* b = dynamic_cast<S_VkArray缓存*>(buf);
	S_VK渲染环境* info = (S_VK渲染环境*)ctx.m_绘图环境;

	VkIndexType type;
	switch (buf->m_Offset) {
	case 2:
		type = VK_INDEX_TYPE_UINT16;
		break;
	case 4:
		type = VK_INDEX_TYPE_UINT32;
		break;
	}
	
	vkCmdBindIndexBuffer(info->m_命令缓存, b->m_Data.m_Buf, 0, type);
}



void f_Draw_序列(S_设备环境& ctx, S_着色线管* 着色线管, S_板载缓存* 顶点, S_渲染参数& 渲染参数) {
	S_VK渲染环境* info = (S_VK渲染环境*)ctx.m_绘图环境;

	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);
	
	f_df_绑定管线(info->m_命令缓存, 着色线管, 渲染参数.m_线管槽);

	assert(顶点);
	f_绑定Vertex(info, (S_VkArray缓存*)顶点);
	vkCmdDraw(info->m_命令缓存, 渲染参数.m_顶点数量, 渲染参数.m_实例数量, 渲染参数.m_顶点内存偏移, 渲染参数.m_实例偏移);
	
}

void f_Draw_间接序列(S_设备环境& ctx, S_着色线管* 着色线管, S_板载缓存* 顶点, S_渲染参数& 渲染参数) {
	S_VK渲染环境* info = (S_VK渲染环境*)ctx.m_绘图环境;

	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);

	f_df_绑定管线(info->m_命令缓存, 着色线管, 渲染参数.m_线管槽);

	f_绑定Vertex(info, (S_VkArray缓存*)顶点);
	vkCmdDrawIndirect(info->m_命令缓存, 
		((S_VkArray缓存*)渲染参数.m_间接->m_Buf)->m_Data.m_Buf, 
		渲染参数.m_间接->m_Mem.m_偏移 * sizeof(VkDrawIndirectCommand), 
		渲染参数.m_间接->m_Mem.m_数量, sizeof(VkDrawIndirectCommand));
}

void f_Draw_索引三角形(S_设备环境& ctx, S_着色线管* 着色线管, S_板载缓存* vert, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数) {
	S_VK渲染环境* info = (S_VK渲染环境*)ctx.m_逻辑设备.渲染环境;

	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);
	

	f_df_绑定管线(info->m_命令缓存, 着色线管, 渲染参数.m_线管槽);


	f_绑定Vertex(info, (S_VkArray缓存*)vert);
	//f_绑定Index(info, (S_VkArray缓存*)索引渲染参数.m_索引);
	if (渲染参数.m_间接) {
		vkCmdDrawIndexedIndirect(info->m_命令缓存, ((S_VkArray缓存*)(渲染参数.m_间接->m_Buf))->m_Data.m_Buf, 0, 渲染参数.m_间接->m_Mem.m_数量, sizeof(VkDrawIndexedIndirectCommand));
	}
	else {
		vkCmdDrawIndexed(info->m_命令缓存, 渲染参数.m_索引内存数量, 渲染参数.m_实例数量, 渲染参数.m_索引内存偏移, 渲染参数.m_顶点内存偏移, 渲染参数.m_实例偏移);
	}
}

void f_Draw2D_索引三角形(S_设备环境& ctx, S_着色线管* 着色线管, S_板载缓存* vert, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数) {
	S_VK渲染环境* info = (S_VK渲染环境*)ctx.m_绘图环境;

	VkRect2D v = *((VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);
	
	f_df_绑定管线(info->m_命令缓存, 着色线管, 渲染参数.m_线管槽);


	f_绑定Vertex(info, (S_VkArray缓存*)vert);
	f_Ex绑定Index(ctx, (S_板载缓存*)索引渲染参数.m_索引);
	vkCmdDrawIndexed(info->m_命令缓存, 渲染参数.m_索引内存数量, 渲染参数.m_实例数量, 渲染参数.m_索引内存偏移, 渲染参数.m_顶点内存偏移, 0);
}





void f_GPU_run计算(S_GPU计算* gpu, uvec3 dim, void* 常量推送, uint32 size, uint8 列队) {
	VkDevice 设备			= (VkDevice)gpu->m_Ctx.m_逻辑设备.设备;
	S_VK渲染环境* info	= (S_VK渲染环境*)f_df_get绘图环境(gpu->m_Ctx);

	S_Vk计算线管* pipeline	= dynamic_cast<S_Vk计算线管*>(gpu->m_Pipeline);
	S_Vk着色* shader		= dynamic_cast<S_Vk着色*>(gpu->m_Shader);

	VkResult result;

	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;


	result = vkResetCommandBuffer(info->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(info->m_命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);


	
	vector<uint32_t> l(1);
	VkDescriptorSet s = (VkDescriptorSet)gpu->m_GPU参数set;
	//VkDescriptorSet* s = (VkDescriptorSet*)(shader->m_DS.data());
	uint32 参数设置数量 = shader->m_DS.size();

	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, (VkPipeline)pipeline->m_线管);
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, shader->m_线管布局, 0, 1, &s, 0, l.data());
	
	if (常量推送) {
		vkCmdPushConstants(info->m_命令缓存, shader->m_线管布局, VK_SHADER_STAGE_COMPUTE_BIT, 0, size, 常量推送);
	}

	vkCmdDispatch(info->m_命令缓存, dim.x, dim.y, dim.z);
	
	result = vkEndCommandBuffer(info->m_命令缓存);
	assert(result == VK_SUCCESS);



	VkFenceCreateInfo fenceCreateInfo{};
	fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceCreateInfo.flags = 0;
	VkFence fence;
	vkCreateFence(info->m_设备, &fenceCreateInfo, nullptr, &fence);

	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = (VkCommandBuffer*)&(info->m_命令缓存);
	result = vkQueueSubmit(info->m_图形列队[列队 ? 列队 : info->m_列队ID], 1, &命令提交信息, fence);
	//result = vkQueueWaitIdle(info->m_图形列队[info->m_列队ID]);
	do {
		result = vkWaitForFences(info->m_设备, 1, &fence, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkDestroyFence(info->m_设备, fence, nullptr);

}

void f_df_run计算(S_GPU计算* gpu, uvec3 dim, S_GPU参数槽& 参数槽, void* 常量推送, uint8 列队) {
	VkDevice 设备 = (VkDevice)gpu->m_Ctx.m_逻辑设备.设备;
	S_VK渲染环境* info = (S_VK渲染环境*)f_df_get绘图环境(gpu->m_Ctx);

	S_Vk计算线管* pipeline = dynamic_cast<S_Vk计算线管*>(gpu->m_Pipeline);
	S_Vk着色* shader = dynamic_cast<S_Vk着色*>(gpu->m_Shader);

	VkResult result;

	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;


	f_df_setGPU参数布局((S_结构指针)设备, 参数槽, false);


	result = vkResetCommandBuffer(info->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(info->m_命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);



	vector<uint32_t> l(1);
	VkDescriptorSet* s = (VkDescriptorSet*)(shader->m_DS.data());
	uint32 参数设置数量 = shader->m_DS.size();
	if (参数设置数量) {
		s = (VkDescriptorSet*)(shader->m_DS.data());
	}
	else {
		参数设置数量 = 1;
		s = (VkDescriptorSet*)&gpu->m_GPU参数set;
	}

	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, (VkPipeline)pipeline->m_线管);
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, shader->m_线管布局, 0, 参数设置数量, s, 0, l.data());

	if (常量推送) {
		//vkCmdPushConstants(info->m_命令缓存, shader->m_线管布局, VK_SHADER_STAGE_COMPUTE_BIT, 0, gpu->m_常量大小, 常量推送);
	}

	vkCmdDispatch(info->m_命令缓存, dim.x, dim.y, dim.z);

	result = vkEndCommandBuffer(info->m_命令缓存);
	assert(result == VK_SUCCESS);



	VkFenceCreateInfo fenceCreateInfo{};
	fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceCreateInfo.flags = 0;
	VkFence fence;
	vkCreateFence(info->m_设备, &fenceCreateInfo, nullptr, &fence);

	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = (VkCommandBuffer*)&(info->m_命令缓存);
	result = vkQueueSubmit(info->m_图形列队[列队 ? 列队 : info->m_列队ID], 1, &命令提交信息, fence);

	do {
		result = vkWaitForFences(info->m_设备, 1, &fence, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkDestroyFence(info->m_设备, fence, nullptr);
}








S_帧缓存* f_bd_创建帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理** colors, uint32 num, bool 多重采样, bool 单一层) {
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)ctx.m_绘图环境;

	S_Vk帧缓存* frameBuf = new S_Vk帧缓存(faceSize);
	frameBuf->m_多重采样 = 多重采样;
	frameBuf->m_设备 = 绘图设备配置->m_设备;


	if (单一层) {
		f_bd_构建帧缓存纹理(ctx, frameBuf, faceSize, colors, num);
	}
	else {
		f_bd_构建帧多重采样缓存(ctx, frameBuf, faceSize, colors, num);
	}

	frameBuf->m_开始渲染信息.clearValueCount = 3;
	return frameBuf;
}

void f_bd_构建帧多重采样缓存(S_设备环境& ctx, S_帧缓存* frame, const uvec2& faceSize, S_纹理** colors, uint32 num) {
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)f_df_get绘图环境(ctx);

	S_Vk帧缓存& frameBuf = *dynamic_cast<S_Vk帧缓存*>(frame);
	uvec3 area = { faceSize.x, faceSize.y, 1 };
	E_MS次数 采样 = frameBuf.m_多重采样 ? ctx.m_采样数 : E_MS次数::e_MS_1;
	bool 开启采样 = ctx.m_采样数 != E_MS次数::e_MS_1 ? true : false;

	frameBuf.m_渲染通道 = 绘图设备配置->m_场景渲染通道;
	if (开启采样) {
		if (frameBuf.m_颜色图像) {
			f_tex_setSize(frameBuf.m_颜色图像, faceSize);
		}
		else {
			frameBuf.m_颜色图像 = f_tex_创建帧缓存纹理(ctx, area, colors[0]->m_格式, E_纹理维度类型::e_2D, 采样);
		}
		frameBuf.m_交换面颜色缓存.push_back((S_VkImage*)(frameBuf.m_颜色图像));
	}
	for (uint32 i = 0; i < num; ++i) {
		frameBuf.m_交换面颜色缓存.push_back((S_VkImage*)(colors[i]));
	}
	
	auto* 深度图像 = f_tex_创建深度纹理(ctx, area, 采样, E_纹理维度类型::e_2D, E_纹理格式::e_tf_D32F);
	frameBuf.m_交换面深度缓存.push_back((S_VkImage*)深度图像);

	//这里采样必须是1
	frameBuf.m_深度图像 = f_tex_创建深度纹理(ctx, area, E_MS次数::e_MS_1, E_纹理维度类型::e_2D, E_纹理格式::e_tf_D32F);
	frameBuf.m_交换面深度缓存.push_back((S_VkImage*)frameBuf.m_深度图像);



	frameBuf.m_Size = faceSize;
	f_frame_构建交换链缓存(frameBuf, ctx.m_采样数 != E_MS次数::e_MS_1 ? true : false);
}

void f_bd_构建帧缓存纹理(S_设备环境& ctx, S_帧缓存* frame, const uvec2& faceSize, S_纹理** colors, uint32 num) {
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_Vk帧缓存& frameBuf = *dynamic_cast<S_Vk帧缓存*>(frame);
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	uvec3 area = { faceSize.x, faceSize.y, 1 };
	E_MS次数 采样 = frameBuf.m_多重采样 ? ctx.m_采样数 : E_MS次数::e_MS_1;

	for (uint32 i = 0; i < num; ++i) {
		frameBuf.m_交换面颜色缓存.push_back((S_VkImage*)(colors[i]));
	}

	auto* 深度图像 = f_tex_创建深度纹理(ctx, area, 采样, E_纹理维度类型::e_2D, E_纹理格式::e_tf_D32F);
	frameBuf.m_交换面深度缓存.push_back((S_VkImage*)深度图像);


	frameBuf.m_渲染通道 = 绘图环境->m_场景渲染通道;
	frameBuf.m_Size = faceSize;
	frameBuf.f_构建交换链缓存(逻辑设备, (VkRenderPass)(frameBuf.m_渲染通道), false);
}

void f_bd_重置帧缓存大小(S_设备环境& ctx, S_帧缓存* frame, const uvec2& faceSize) {
	S_Vk帧缓存& frameBuf = *dynamic_cast<S_Vk帧缓存*>(frame);
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);

	frameBuf.f_release();
	frameBuf.f_构建交换链缓存(逻辑设备, (VkRenderPass)(frameBuf.m_渲染通道), 1);
}


S_设备环境* f_df_创建渲染环境(S_设备环境& ctx, E_纹理格式 cf, E_纹理格式 df, E_MS次数 采样, uint16 线程数) {
	S_设备环境* drawCtx = (S_设备环境*)malloc(sizeof(S_设备环境));
	(*drawCtx) = ctx;
	
	VkDevice 逻辑设备			= (VkDevice)(ctx.m_逻辑设备.设备);
	S_VK渲染环境* 绘图设备配置	= (S_VK渲染环境*)(ctx.m_逻辑设备.渲染环境);
	S_VK渲染环境* 绘图配置		= (S_VK渲染环境*)malloc(sizeof(S_VK渲染环境));
	

	(*绘图配置) = (*绘图设备配置);
	绘图配置->m_列队ID = 1;
	绘图配置->m_命令缓存数 = 线程数;

	绘图配置->m_交换链帧缓存 = (S_Vk帧缓存*)0xffffffff;
	绘图配置->m_窗口UI渲染通道 = f_创建UI渲染通道(逻辑设备, f_vk_getVK图像格式(cf));
	绘图配置->m_窗口UI合成通道 = f_fb_创建渲染通道(逻辑设备, VK_FORMAT_B8G8R8A8_UNORM, true);

	绘图配置->m_场景渲染通道 = f_创建纹理渲染通道(逻辑设备, f_vk_getVK图像格式(cf), f_vk_getVK图像格式(df), 采样);
	绘图配置->m_阴影渲染通道 = f_创建阴影渲染通道(逻辑设备, f_vk_getVK图像格式(df));
	绘图配置->m_环境渲染通道 = f_fb_创建环境渲染通道(逻辑设备, cf, df);
	绘图配置->m_几何缓存渲染通道 = f_fb_创建几何缓存渲染通道(逻辑设备, f_vk_getVK图像格式(E_纹理格式::e_tf_RGBA32), f_vk_getVK图像格式(E_纹理格式::e_tf_D32F));
	

	VkResult result;
	绘图配置->m_命令开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	绘图配置->m_命令开始信息.pNext = nullptr;
	绘图配置->m_命令开始信息.flags = 0;
	绘图配置->m_命令开始信息.pInheritanceInfo = 0;
	

	//二级命令缓冲的继承信息
	绘图配置->m_二级命令缓存继承信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;		//结构体类型
	绘图配置->m_二级命令缓存继承信息.pNext = NULL;
	绘图配置->m_二级命令缓存继承信息.renderPass = nullptr;
	绘图配置->m_二级命令缓存继承信息.subpass = 0;													//设置渲染子通道数量
	绘图配置->m_二级命令缓存继承信息.occlusionQueryEnable = VK_FALSE;								//关闭遮挡查询
	绘图配置->m_二级命令缓存继承信息.queryFlags = 0;												//设置查询标志
	绘图配置->m_二级命令缓存继承信息.pipelineStatistics = 0;										//控制统计如何执行的附加标志


	绘图配置->m_二级渲染开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	绘图配置->m_二级渲染开始信息.pNext = nullptr; 
	绘图配置->m_二级渲染开始信息.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	绘图配置->m_二级渲染开始信息.pInheritanceInfo = &(绘图配置->m_二级命令缓存继承信息);			//命令缓冲继承信息


	/************************************************************************************/
	//                        命令缓存创建  主命令和子命令缓存
	/************************************************************************************/
	VkCommandPoolCreateInfo cmd_pool_info = {};														//构建命令池创建信息结构体实例
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL;																		//自定义数据的指针
	cmd_pool_info.queueFamilyIndex = 绘图设备配置->绘图列队家族Offset;								//绑定队列家族索引
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(绘图配置->m_命令缓存池));
	assert(result == VK_SUCCESS);															
	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(绘图配置->m_二级命令管道));
	assert(result == VK_SUCCESS);													


	VkCommandBufferAllocateInfo cmdalloc = {}; 
	cmdalloc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmdalloc.pNext = NULL; 
	
	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 绘图配置->m_命令缓存池;										//绑定命令池
	cmdalloc.commandBufferCount = 1;													//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, &(绘图配置->m_命令缓存));
	assert(result == VK_SUCCESS);

	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 绘图配置->m_二级命令管道;									//绑定命令池
	cmdalloc.commandBufferCount = 线程数;												//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, 绘图配置->m_二级命令缓存);
	assert(result == VK_SUCCESS);



	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;
	result = vkCreateSemaphore(逻辑设备, &图像信号创建信息, NULL, &绘图配置->m_图像获取信号量);
	assert(result == VK_SUCCESS);


	VkFenceCreateInfo fenceInfo;
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceInfo.pNext = NULL;
	fenceInfo.flags = 0;
	vkCreateFence(逻辑设备, &fenceInfo, NULL, &(绘图配置->m_同步围栏));

	

	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	绘图配置->m_命令提交信息 = {};
	绘图配置->m_命令提交信息.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	绘图配置->m_命令提交信息.pWaitDstStageMask = waitStages;

	//创建缓存需要设置信号量
	绘图配置->m_命令提交信息.waitSemaphoreCount = 0;
	绘图配置->m_命令提交信息.pWaitSemaphores = 0;

	绘图配置->m_命令提交信息.commandBufferCount = 1;
	绘图配置->m_命令提交信息.pCommandBuffers = &绘图配置->m_命令缓存;

	绘图配置->m_命令提交信息.signalSemaphoreCount = 0;
	绘图配置->m_命令提交信息.pSignalSemaphores = 0;


	绘图配置->m_物理设备 = (VkPhysicalDevice)(ctx.m_物理设备.设备);

	drawCtx->m_逻辑设备.渲染环境 = (S_结构指针)绘图配置;
	drawCtx->m_绘图环境 = (S_渲染环境*)绘图配置;
	drawCtx->m_采样数 = 采样;
	drawCtx->m_全局设备ID = (ctx.m_物理设备.ID << 16) | ctx.m_逻辑设备.队列族索引;
	
	drawCtx->m_绘图环境->m_2D渲染管线 = (S_2D渲染线管集*)malloc(sizeof(S_2D渲染线管集));
	drawCtx->m_绘图环境->m_3D渲染管线 = (S_3D渲染线管集*)malloc(sizeof(S_3D渲染线管集));

	f_surface2D_管线创建(*drawCtx);
	f_surface3D_管线创建(*drawCtx);
	return drawCtx;
}

S_设备环境* f_创建计算环境(S_设备环境& ctx, uint16 线程数) {
	S_设备环境* compCtx = (S_设备环境*)malloc(sizeof(S_设备环境));
	(*compCtx) = ctx;

	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_VK渲染环境* old绘图设备配置 = (S_VK渲染环境*)(ctx.m_逻辑设备.渲染环境);



	S_VK渲染环境* 计算配置 = (S_VK渲染环境*)malloc(sizeof(S_VK渲染环境));
	compCtx->m_逻辑设备.渲染环境 = (S_结构指针)计算配置;

	(*计算配置) = (*old绘图设备配置);
	计算配置->m_列队ID = 2;
	计算配置->m_命令缓存数 = 线程数;


	VkResult result;
	//二级命令缓冲的继承信息
	计算配置->m_二级命令缓存继承信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;		//结构体类型
	计算配置->m_二级命令缓存继承信息.pNext = NULL;
	计算配置->m_二级命令缓存继承信息.subpass = 0;													//设置渲染子通道数量
	计算配置->m_二级命令缓存继承信息.occlusionQueryEnable = VK_FALSE;								//关闭遮挡查询
	计算配置->m_二级命令缓存继承信息.queryFlags = 0;												//设置查询标志
	计算配置->m_二级命令缓存继承信息.pipelineStatistics = 0;										//控制统计如何执行的附加标志


	计算配置->m_二级渲染开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	计算配置->m_二级渲染开始信息.pNext = NULL; //自定义数据指针
	计算配置->m_二级渲染开始信息.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	计算配置->m_二级渲染开始信息.pInheritanceInfo = &(计算配置->m_二级命令缓存继承信息);			//命令缓冲继承信息



	/************************************************************************************/
	//                        命令缓存创建  主命令和子命令缓存
	/************************************************************************************/

	VkCommandPoolCreateInfo cmd_pool_info = {}; //构建命令池创建信息结构体实例
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL; //自定义数据的指针
	cmd_pool_info.queueFamilyIndex = old绘图设备配置->绘图列队家族Offset;//绑定队列家族索引
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(计算配置->m_命令缓存池));
	assert(result == VK_SUCCESS); //检查命令池是否创建成功

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(计算配置->m_二级命令管道));
	assert(result == VK_SUCCESS); //检查命令池是否创建成功



	VkCommandBufferAllocateInfo cmdalloc = {};
	cmdalloc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmdalloc.pNext = NULL;

	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 计算配置->m_命令缓存池;										//绑定命令池
	cmdalloc.commandBufferCount = 1;													//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, &(计算配置->m_命令缓存));
	assert(result == VK_SUCCESS);

	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 计算配置->m_二级命令管道;									//绑定命令池
	cmdalloc.commandBufferCount = 线程数;												//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, 计算配置->m_二级命令缓存);
	assert(result == VK_SUCCESS);




	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;
	result = vkCreateSemaphore(逻辑设备, &图像信号创建信息, NULL, &计算配置->m_图像获取信号量);
	assert(result == VK_SUCCESS);




	VkFenceCreateInfo fenceInfo;
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceInfo.pNext = NULL;
	fenceInfo.flags = 0;
	vkCreateFence(逻辑设备, &fenceInfo, NULL, &(计算配置->m_同步围栏));


	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
	计算配置->m_命令提交信息 = {};
	计算配置->m_命令提交信息.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	计算配置->m_命令提交信息.pWaitDstStageMask = waitStages;

	计算配置->m_命令提交信息.waitSemaphoreCount = 0;
	计算配置->m_命令提交信息.pWaitSemaphores = 0;

	计算配置->m_命令提交信息.commandBufferCount = 1;
	计算配置->m_命令提交信息.pCommandBuffers = &计算配置->m_命令缓存;

	计算配置->m_命令提交信息.signalSemaphoreCount = 0;
	计算配置->m_命令提交信息.pSignalSemaphores = 0;

	return compCtx;
}

bool f_df_销毁渲染环境(S_设备环境& ctx) {
	auto dc = f_vk_get绘图环境(ctx);
	auto 设备 = f_vk_getDevice(ctx);

	f_pipe_销毁着色参数设置(ctx);
	vkDestroyFence(设备, dc->m_同步围栏, nullptr);
	free(ctx.m_绘图环境->m_2D渲染管线);

	return false;
}





void f_Draw_Begin_帧缓存(S_设备环境& ctx, S_帧缓存* frame, uint8 id, bool 阴影) {
	VkResult result;
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	result = vkResetCommandBuffer(绘图环境->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(绘图环境->m_命令缓存, &绘图环境->m_命令开始信息);
	assert(result == VK_SUCCESS);

	S_Vk帧缓存* 帧 = static_cast<S_Vk帧缓存*>(frame);

	帧->m_开始渲染信息.renderPass = 帧->m_渲染通道;
	帧->m_开始渲染信息.framebuffer = 帧->m_帧缓存[id];
	帧->m_开始渲染信息.clearValueCount = 帧->m_颜色通道数量 + 帧->m_深度通道数量;
	for (uint32 i = 0; i < 帧->m_颜色通道数量; ++i) {
		帧->m_背景清除值[i].color.float32[0] = 帧->m_清除颜色.x;
		帧->m_背景清除值[i].color.float32[1] = 帧->m_清除颜色.y;
		帧->m_背景清除值[i].color.float32[2] = 帧->m_清除颜色.z;
		帧->m_背景清除值[i].color.float32[3] = 帧->m_清除颜色.w;
	}
	for (uint32 i = 0; i < 帧->m_深度通道数量; ++i) {
		帧->m_背景清除值[帧->m_颜色通道数量 + i].depthStencil = {1, 0};
	}

	vkCmdBeginRenderPass(绘图环境->m_命令缓存, &帧->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);
}

void f_Draw_Begin_帧缓存(S_设备环境& ctx, S_帧缓存* frame, uint8 id, S_Rect2D rect) {
	VkResult result;
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	result = vkResetCommandBuffer(绘图环境->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(绘图环境->m_命令缓存, &绘图环境->m_命令开始信息);
	assert(result == VK_SUCCESS);

	S_Vk帧缓存* 帧 = static_cast<S_Vk帧缓存*>(frame);

	帧->m_开始渲染信息.renderPass = 帧->m_渲染通道;
	帧->m_开始渲染信息.framebuffer = 帧->m_帧缓存[id];
	帧->m_开始渲染信息.clearValueCount = 帧->m_颜色通道数量 + 帧->m_深度通道数量;
	for (uint32 i = 0; i < 帧->m_颜色通道数量; ++i) {
		帧->m_背景清除值[i].color.float32[0] = 帧->m_清除颜色.x;
		帧->m_背景清除值[i].color.float32[1] = 帧->m_清除颜色.y;
		帧->m_背景清除值[i].color.float32[2] = 帧->m_清除颜色.z;
		帧->m_背景清除值[i].color.float32[3] = 帧->m_清除颜色.w;
	}
	for (uint32 i = 0; i < 帧->m_深度通道数量; ++i) {
		帧->m_背景清除值[帧->m_颜色通道数量 + i].depthStencil = {1, 0};
	}

	auto 帧开始渲染信息 = 帧->m_开始渲染信息;
	帧开始渲染信息.renderArea = *((VkRect2D*)(&rect));

	vkCmdBeginRenderPass(绘图环境->m_命令缓存, &帧开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);
}

void f_Draw_end_帧缓存(S_设备环境& ctx) {
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	vkCmdEndRenderPass(绘图环境->m_命令缓存);

	auto result = vkEndCommandBuffer(绘图环境->m_命令缓存);
	assert(result == VK_SUCCESS);
	
	绘图环境->m_命令提交信息.pCommandBuffers = &绘图环境->m_命令缓存;
	result = vkQueueSubmit(绘图环境->m_图形列队[绘图环境->m_列队ID], 1, &(绘图环境->m_命令提交信息), 绘图环境->m_同步围栏);
	assert(result == VK_SUCCESS);
	
	do {
		result = vkWaitForFences(绘图环境->m_设备, 1, &绘图环境->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkResetFences(绘图环境->m_设备, 1, &绘图环境->m_同步围栏);
}






void f_df_BeginDraw(S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id, uint32 清除数量) {
	VkResult result;
	S_VK渲染环境* 配置 = ((S_VK渲染环境*)绘图配置->m_绘图环境);


	result = vkResetCommandBuffer(配置->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(配置->m_命令缓存, &配置->m_命令开始信息);
	assert(result == VK_SUCCESS);

	VkClearValue 清除颜色[5] = { {0,0,0,0} };

	switch (清除数量) {
		case 5: {
			for (uint32 i = 0; i < 4; ++i) {
				清除颜色[i].color.float32[0] = frame->m_清除颜色.x;
				清除颜色[i].color.float32[1] = frame->m_清除颜色.y;
				清除颜色[i].color.float32[2] = frame->m_清除颜色.z;
				清除颜色[i].color.float32[3] = frame->m_清除颜色.w;
			}
			清除颜色[4].depthStencil.depth = 1.0;
			清除颜色[4].depthStencil.stencil = 1;
			break;
		}
		case 3: {
			清除颜色[2].color.float32[0] = frame->m_清除颜色.x;
			清除颜色[2].color.float32[1] = frame->m_清除颜色.y;
			清除颜色[2].color.float32[2] = frame->m_清除颜色.z;
			清除颜色[2].color.float32[3] = frame->m_清除颜色.w;

			清除颜色[2].depthStencil.depth = 1.0;
			清除颜色[2].depthStencil.stencil = 0;
		}
		case 2: {
			清除颜色[0].color.float32[0] = frame->m_清除颜色.x;
			清除颜色[0].color.float32[1] = frame->m_清除颜色.y;
			清除颜色[0].color.float32[2] = frame->m_清除颜色.z;
			清除颜色[0].color.float32[3] = frame->m_清除颜色.w;
			
			清除颜色[1].depthStencil.depth = 1.0;
			清除颜色[1].depthStencil.stencil = 0;
			break;
		}
		case 1: {
			清除颜色[0].color.float32[0] = frame->m_清除颜色.x;
			清除颜色[0].color.float32[1] = frame->m_清除颜色.y;
			清除颜色[0].color.float32[2] = frame->m_清除颜色.z;
			清除颜色[0].color.float32[3] = frame->m_清除颜色.w;

			清除颜色[0].depthStencil.depth = 1.0;
			清除颜色[0].depthStencil.stencil = 0;
		}
		default:
			break;
	}
	
	S_Vk帧缓存* 帧 = static_cast<S_Vk帧缓存*>(frame);
}






void f_Draw_Begin(S_设备环境* ctx, S_结构指针 命令缓存, S_结构指针 fence) {
	S_VK渲染环境* 配置 = ((S_VK渲染环境*)ctx->m_绘图环境);

	auto result = vkResetCommandBuffer((VkCommandBuffer)命令缓存, 0);
	assert(result == VK_SUCCESS);

	VkCommandBufferBeginInfo cmdBufferBeginInfo{};
	cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	
	result = vkBeginCommandBuffer((VkCommandBuffer)命令缓存, &cmdBufferBeginInfo);
	assert(result == VK_SUCCESS);
}

void f_Draw_end(S_设备环境* ctx, S_结构指针 命令缓存, S_结构指针 fence, uint8 列队) {
	S_VK渲染环境* 配置 = ((S_VK渲染环境*)ctx->m_绘图环境);

	auto result = vkEndCommandBuffer((VkCommandBuffer)命令缓存);
	assert(result == VK_SUCCESS);

	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = (VkCommandBuffer*)&命令缓存;
	
	//result = vkQueueSubmit(配置->m_图形列队[列队], 1, &命令提交信息, VK_NULL_HANDLE);
	//assert(result == VK_SUCCESS);
	//result = vkQueueWaitIdle(配置->m_图形列队[列队]);
	//assert(result == VK_SUCCESS);
	//vkDeviceWaitIdle(配置->m_设备);
	//return;

	result = vkQueueSubmit(配置->m_图形列队[列队], 1, &命令提交信息, (VkFence)fence);
	assert(result == VK_SUCCESS);
	do {
		result = vkWaitForFences(配置->m_设备, 1, (VkFence*)&fence, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	result = vkResetFences(配置->m_设备, 1, ((VkFence*)&fence));
	assert(result == VK_SUCCESS);
}


/*
引发了异常: 读取访问权限冲突。
**image_state** 是 nullptr。
* 
*/




void f_Draw_构建顶层加速结构(S_设备环境* ctx, S_帧缓存* frame, uint8 id) {
	auto* 绘图环境 = f_vk_get绘图环境(*ctx);
	auto* 绘图框架 = f_vk_get绘图框架(*ctx);
	
	auto mat = f_mat34_identity();
	auto* 光追实例 = f_buf_create板载缓存(*ctx, sizeof(VkAccelerationStructureInstanceKHR), E_板载缓存类型::e_光追实例, 1);
	auto ptr_instance = f_buf_map板载缓存<VkAccelerationStructureInstanceKHR>(光追实例);
	ptr_instance[0].transform = *((VkTransformMatrixKHR*)&mat);
	ptr_instance[0].instanceCustomIndex = 0;
	ptr_instance[0].mask = 0xFF;
	ptr_instance[0].instanceShaderBindingTableRecordOffset = 0;
	ptr_instance[0].flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
	//instance.accelerationStructureReference = bottomLevelAS.deviceAddress;
	f_buf_unmap板载缓存(光追实例);

	
	uint32 物体数量 = 1;
	std::vector<VkAccelerationStructureGeometryKHR> 几何加速结构;
	for (uint32 i = 0; i < 物体数量; ++i) {
		VkAccelerationStructureGeometryKHR asg{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR }; {
			asg.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
			asg.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
			asg.geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
			asg.geometry.instances.arrayOfPointers = VK_FALSE;
			VkDeviceOrHostAddressConstKHR 实例数据{};
			实例数据.deviceAddress = f_buf_getAddress(static_cast<S_VkArray缓存*>(光追实例));
			asg.geometry.instances.data = 实例数据;
		}
		几何加速结构.push_back(asg);
	}
	
	

	VkAccelerationStructureBuildGeometryInfoKHR 加速结构绑定几何信息{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR };
	加速结构绑定几何信息.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
	加速结构绑定几何信息.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
	加速结构绑定几何信息.geometryCount = 几何加速结构.size();
	加速结构绑定几何信息.pGeometries = 几何加速结构.data();


	uint32_t primitive_count = 1;
	VkAccelerationStructureBuildSizesInfoKHR accelerationStructureBuildSizesInfo{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
	绘图框架->vkGetAccelerationStructureBuildSizes(
		绘图环境->m_设备,
		VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
		&加速结构绑定几何信息,
		&primitive_count,
		&accelerationStructureBuildSizesInfo);

	auto as = f_buf_create板载缓存(*ctx, 1, E_板载缓存类型::e_光追顶层加速结构, accelerationStructureBuildSizesInfo.accelerationStructureSize);
	

	//在构建顶级加速结构期间创建一个小的暂存缓冲区
	auto* 暂存缓冲区 = f_buf_create板载缓存(*ctx, 1, E_板载缓存类型::e_SSBO, accelerationStructureBuildSizesInfo.accelerationStructureSize);


	加速结构绑定几何信息.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
	加速结构绑定几何信息.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
	加速结构绑定几何信息.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
	加速结构绑定几何信息.dstAccelerationStructure = f_buf_get加速结构地址(as);
	加速结构绑定几何信息.scratchData.deviceAddress = f_buf_getAddress(static_cast<S_VkArray缓存*>(暂存缓冲区));


	VkAccelerationStructureBuildRangeInfoKHR 绑定偏移信息{};
	VkAccelerationStructureBuildRangeInfoKHR* ptr_绑定偏移信息 = &绑定偏移信息;
	VkBufferDeviceAddressInfo 缓存信息{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
	

	绘图框架->vkCmdBuildAccelerationStructures(绘图环境->m_命令缓存, 1, &加速结构绑定几何信息, &ptr_绑定偏移信息);
}

void f_Draw2D多边形(S_设备环境& ctx, S_渲染参数& 渲染参数, bool 是否填充) {

}




S_GPU计算* f_df_创建并行计算(S_设备环境& ctx, std::string path, const std::vector<S_着色器创建参数>& 参数配置, const std::vector<S_常量推送创建参数>& 常量, bool 自定义布局) {
	S_GPU计算* mat = new S_GPU计算(&ctx);
	S_着色器创建配置 图元配置 = {
		{
			参数配置
		},
		{ },
		{
			{path, {}, E_着色阶段::e_计算着色},
		},
		{
			常量
		}
	};

	mat->m_Ctx = ctx;
	if (自定义布局) {
		mat->m_参数布局 = f_df_创建着色器参数布局(f_df_getVK设备(ctx), 参数配置, nullptr);
		mat->m_Shader = f_create着色(ctx, 图元配置, &mat->m_参数布局, 1);
		mat->m_Pipeline = f_df_创建计算线管(ctx, *mat->m_Shader);
	}
	else {
		mat->m_Shader = f_create着色(ctx, 图元配置);
		mat->m_Pipeline = f_df_创建计算线管(ctx, *mat->m_Shader);
		mat->m_Shader->f_alloc参数设置(&(mat->m_GPU参数set));
	}

	return mat;
}


void f_df_销毁并行计算(S_GPU计算* in) {
	delete in;
}




bool f_device_是否支持光追(const S_设备& dev) {
	if (((const S_物理设备属性*)(dev.物理设备.物理设备属性))->m_支持光追) {
		return true;
	}
	return false;
}

bool f_device_是否支持光追(const S_物理设备& dev) {
	if (((const S_物理设备属性*)(dev.物理设备属性))->m_支持光追) {
		return true;
	}
	return false;
}


S_设备 f_get最强计算性能设备(const std::vector<S_设备>& 设备) {
	std::map<uint32, S_设备> 排序设备;

	for (auto& e : 设备) {
		S_物理设备属性* prop = (S_物理设备属性*)e.物理设备.物理设备属性;

		排序设备[prop->m_3D纹理最大分辨率] = e;
	}
	
	if (排序设备.size()) {
		auto d = (*(--排序设备.end())).second;
		//auto d = (*(排序设备.begin())).second;
		std::cout<<"计算设备:"<<d.物理设备.ID<<" "<<d.逻辑设备.size()<<std::endl;
		return d;
	}
	std::cout << "error : 没有计算设备" << std::endl;
	return S_设备();
}



uvec3 f_df_get全局最大线程(S_设备环境& ctx) {
	//auto* 绘图框架 = f_vk_get绘图框架(ctx);
	auto* 绘图环境 = f_vk_get绘图环境(ctx);
	//dc.m_设备属性.limits.maxComputeWorkGroupSize;
	return { 绘图环境->m_设备属性.limits.maxComputeWorkGroupCount[0], 
             绘图环境->m_设备属性.limits.maxComputeWorkGroupCount[1], 
             绘图环境->m_设备属性.limits.maxComputeWorkGroupCount[2] 
	};
}

uvec3 f_df_get本地最大线程(S_设备环境& ctx) {
	//auto* 绘图框架 = f_vk_get绘图框架(ctx);
	auto* 绘图环境 = f_vk_get绘图环境(ctx);
	//dc.m_设备属性.limits.maxComputeWorkGroupSize;
	return { 绘图环境->m_设备属性.limits.maxComputeWorkGroupSize[0], 
             绘图环境->m_设备属性.limits.maxComputeWorkGroupSize[1],
             绘图环境->m_设备属性.limits.maxComputeWorkGroupSize[2] 
	};
}

uint32 f_def_get本地最大线程数量(S_设备环境& ctx) {
	//auto* 绘图框架 = f_vk_get绘图框架(ctx);
	auto* 绘图环境 = f_vk_get绘图环境(ctx);
	return 绘图环境->m_设备属性.limits.maxComputeWorkGroupInvocations;
}



S_GlobalParam f_df_全局GPU参数() {
	S_GlobalParam 全局参数 = {
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_I32动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_UI32动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_F32动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_Vec2动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_Vec3动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_Vec4动态属性)),

		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_iVec2动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_iVec3动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_iVec4动态属性)),

		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_uVec2动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_uVec3动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_uVec4动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_Mat44动态属性)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_采样曲线属性)),

		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_平行光缓冲区)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_点光源缓冲区)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_区域光缓冲区)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().m_聚光灯缓冲区)),

		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_材质)),


		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_I32动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_UI32动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_F32动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_Vec2动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_Vec3动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_Vec4动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_iVec2动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_iVec3动态属性_点)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_iVec4动态属性_点)),

		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_I32动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_UI32动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_F32动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_Vec2动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_Vec3动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_Vec4动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_iVec2动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_iVec3动态属性_面)),
		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_iVec4动态属性_面)),

		f_buf_getAddress(static_cast<S_VkArray缓存*>(f_buf_getGlobal().g_实例材质ID)),

		//0,
		//0,
		//0,
		//0,
	};


	全局参数.m_I32Num	= f_buf_getGlobal().m_I32动态属性->m_Size;
	全局参数.m_UI32Num	= f_buf_getGlobal().m_UI32动态属性->m_Size;
	全局参数.m_F32Num	= f_buf_getGlobal().m_F32动态属性->m_Size;
	全局参数.m_Vec2Num	= f_buf_getGlobal().m_Vec2动态属性->m_Size;
	全局参数.m_Vec3Num	= f_buf_getGlobal().m_Vec3动态属性->m_Size;
	全局参数.m_Vec4Num	= f_buf_getGlobal().m_Vec4动态属性->m_Size;

	全局参数.m_iVec2Num = f_buf_getGlobal().m_iVec2动态属性->m_Size;
	全局参数.m_iVec3Num = f_buf_getGlobal().m_iVec3动态属性->m_Size;
	全局参数.m_iVec4Num = f_buf_getGlobal().m_iVec4动态属性->m_Size;

	全局参数.m_uVec2Num = f_buf_getGlobal().m_uVec2动态属性->m_Size;
	全局参数.m_uVec3Num = f_buf_getGlobal().m_uVec3动态属性->m_Size;
	全局参数.m_uVec4Num = f_buf_getGlobal().m_uVec4动态属性->m_Size;


	全局参数.m_Num_LigthParallel = 0;
	全局参数.m_Num_LigthPoint = 0;
	全局参数.m_Num_LigthSpot = 0;
	全局参数.m_Num_LigthArea = 0;

	return 全局参数;
}






void f_df_光追渲染(GLSL_RenderFrame& 帧渲染参数, S_光追后端* 光追后端) {
	//auto* 绘图环境 = f_vk_get绘图环境(*光追后端->m_Ctx);
	auto* 绘图框架 = f_vk_get绘图框架(*光追后端->m_Ctx);

	VkDescriptorSet DS = (VkDescriptorSet)(光追后端->m_GPU参数设置);

	C_Vk光追后端& 后端 = *(C_Vk光追后端*)光追后端;

	f_Draw_Begin(光追后端->m_Ctx, 光追后端->m_渲染命令缓存, 光追后端->g_渲染Fence);


	vkCmdBindPipeline((VkCommandBuffer)后端.m_渲染命令缓存, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, static_cast<S_Vk光追线管*>(后端.m_光追管线)->m_线管);
	vkCmdBindDescriptorSets((VkCommandBuffer)后端.m_渲染命令缓存, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, static_cast<S_Vk光追线管*>(后端.m_光追管线)->m_线管布局, 0, 1, &DS, 0, 0);

	VkStridedDeviceAddressRegionKHR emptySbtEntry = {};

	绘图框架->vkCmdTraceRays((VkCommandBuffer)光追后端->m_渲染命令缓存,
		&后端.m_光追生成GPU地址,
		&后端.m_光追忽略GPU地址,
		&后端.m_光追相交GPU地址,
		&后端.m_光追回调GPU地址,
		//&emptySbtEntry,
		后端.m_渲染配置.m_瓦片分辨率.x,
		后端.m_渲染配置.m_瓦片分辨率.y,
		1
	);

	f_Draw_end(后端.m_Ctx, 后端.m_渲染命令缓存, 后端.g_渲染Fence, 3);
}




void f_df_钳制视口大小(S_设备环境& ctx, ivec2& viewSize) {
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	viewSize.x = min(viewSize.x, 绘图环境->m_设备属性.limits.maxViewportDimensions[0]);
	viewSize.y = min(viewSize.y, 绘图环境->m_设备属性.limits.maxViewportDimensions[1]);
}

void f_df_钳制视口大小(S_设备环境& ctx, uvec2& viewSize) {
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	viewSize.x = min(viewSize.x, 绘图环境->m_设备属性.limits.maxViewportDimensions[0]);
	viewSize.y = min(viewSize.y, 绘图环境->m_设备属性.limits.maxViewportDimensions[1]);
}

void f_df_钳制纹理大小(S_设备环境& ctx, uvec2& viewSize) {
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	viewSize.x = min(viewSize.x, 绘图环境->m_设备属性.limits.maxImageDimension2D);
	viewSize.y = min(viewSize.y, 绘图环境->m_设备属性.limits.maxImageDimension2D);
}

void f_df_钳制纹理大小(S_设备环境& ctx, uvec3& viewSize) {
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	viewSize.x = min(viewSize.x, 绘图环境->m_设备属性.limits.maxImageDimension3D);
	viewSize.y = min(viewSize.y, 绘图环境->m_设备属性.limits.maxImageDimension3D);
	viewSize.z = min(viewSize.z, 绘图环境->m_设备属性.limits.maxImageDimension3D);

	viewSize.x = max(viewSize.x, 1);
	viewSize.y = max(viewSize.y, 1);
	viewSize.z = max(viewSize.z, 1);
}




void f_df_setGPU参数槽(S_结构指针 device, S_结构指针 GPU参数设置, const S_GPU参数槽& GPU参数) {
	if (!GPU参数.m_绑定数量) return;

	VkDevice 设备 = (VkDevice)device;
	VkDescriptorSet DS = (VkDescriptorSet)GPU参数设置;

	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量);

	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		writes[i].pImageInfo = 0;
		writes[i].pNext = nullptr;

		switch (GPU参数.m_参数类型[i]) {
			case E_板载缓存类型::e_光追BVH: {
				VkWriteDescriptorSetAccelerationStructureKHR* info = (VkWriteDescriptorSetAccelerationStructureKHR*)malloc(sizeof(VkWriteDescriptorSetAccelerationStructureKHR));
				(*info) = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR };
				(*info).accelerationStructureCount = 1;
				(*info).pAccelerationStructures = &f_buf_get加速结构地址((S_VkArray缓存*)(GPU参数.m_参数槽[i]));
				writes[i].pNext = info;

				break;
			}

			case E_板载缓存类型::e_纹理储存_Array:
			case E_板载缓存类型::e_IMAGE_Array:
			case E_板载缓存类型::e_SAMPLER_Array:
			case E_板载缓存类型::e_IMAGE_SAMPLER: {
				writes[i].pImageInfo = (VkDescriptorImageInfo*)(GPU参数.m_参数槽[i]);
				writes[i].descriptorCount = GPU参数.m_绑定数量[i];
				break;
			}

			case E_板载缓存类型::e_SAMPLER:
			case E_板载缓存类型::e_IMAGE: {
				writes[i].pImageInfo = &(((S_VkImage*)(GPU参数.m_参数槽[i]))->m_纹理信息);
				writes[i].descriptorCount = 1;
				break;
			}
			default: {
				auto buf = static_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);
				writes[i].pBufferInfo = &buf->m_Data.m_Buffer_info;
				writes[i].descriptorCount = 1;
				break;
			}
		}

		writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;

		writes[i].descriptorCount = GPU参数.m_绑定数量[i];
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(E_板载缓存类型(GPU参数.m_参数类型[i]));
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding = GPU参数.m_绑定位置[i];									//目标绑定编号
		writes[i].dstSet = DS;

	}

	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, VK_NULL_HANDLE);

	for (auto& e : writes) {
		if (e.pNext) free(const_cast<void*>(e.pNext));
	}
}





/*S_设备环境 f_创建协处理器设备(uint32 物理设备, E_设备类型 类型, E_绘图API apiName) {
	//S_协处理设备* dev = (S_协处理设备*)malloc(sizeof(S_协处理设备));
	S_设备环境 ctx;
	ctx.m_Type = E_绘图API::E_Vulkan;
	ctx.m_物理设备 = g_绘图框架->f_取物理设备(物理设备);

	switch (类型) {
		case E_设备类型::e_绘图设备:
			ctx.m_逻辑设备 = g_绘图框架->f_创建图形逻辑设备(ctx.m_物理设备);
			break;
		case E_设备类型::e_计算设备:
			ctx.m_逻辑设备 = g_绘图框架->f_创建计算逻辑设备(ctx.m_物理设备);
			break;
	}

	g_绘图框架->f_创建命令缓存池(ctx.m_逻辑设备);
	g_绘图框架->f_创建命令缓存(ctx.m_逻辑设备, 0);
	g_绘图框架->f_创建同步围栏(ctx.m_逻辑设备);

	return ctx;
}*/








